package com.zz.rpc;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.Socket;

/**
 * @author zz
 * @Date 2022/5/13
 */
public class ProcessorHandler implements Runnable {


    Socket socket;

    Object service;

    public Socket getSocket() {
        return socket;
    }

    public void setSocket(Socket socket) {
        this.socket = socket;
    }

    public Object getService() {
        return service;
    }

    public void setService(Object service) {
        this.service = service;
    }

    public ProcessorHandler(Socket socket, Object service) {
        this.socket = socket;
        this.service = service;
    }
//    public ProcessorHandler(Socket socket) {
//        this.socket = socket;
//    }

    //当有IO数据过来的时候会执行此方法
    @Override
    public void run() {
        ObjectInputStream objectInputStream = null;
        ObjectOutputStream objectOutputStream = null;
        try {

            objectInputStream = new ObjectInputStream(socket.getInputStream());
            //objectInputStream里面应该有客户端请求方法的参数，请求的方法名称，请求的目标类，请求的参数类型

            //反序列化
            RpcReequest rpcReequest= (RpcReequest) objectInputStream.readObject();
            Object result=invoke(rpcReequest);
            objectOutputStream = new ObjectOutputStream(socket.getOutputStream());

            //序列化,写到网络通信中
            objectOutputStream.writeObject(result);
            objectOutputStream.flush();
        } catch (IOException | ClassNotFoundException |InvocationTargetException|NoSuchMethodException|IllegalAccessException e) {
            e.printStackTrace();
        } finally {
            if(objectInputStream!=null){
                try {
                    objectInputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            if (objectOutputStream!=null){
                try {
                    objectOutputStream.close();
                }catch (IOException e){
                    e.printStackTrace();
                }
            }
        }

    }

    /**
     * 根据客户端传输的request信息来调用方法返回结果
     * @param rpcReequest
     * @return
     * @throws ClassNotFoundException
     * @throws NoSuchMethodException
     * @throws InvocationTargetException
     * @throws IllegalAccessException
     */
    private Object invoke(RpcReequest rpcReequest) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        Object[] params=rpcReequest.getParams(); //请求参数
        Class<?>[] types=new Class[params.length]; //请求参数类型
        for (int i=0;i<params.length;i++){
            types[i]=params[i].getClass();

        }
        Class clazz=Class.forName(rpcReequest.getClassName());//获取请求目标类
        Method method=clazz.getMethod(rpcReequest.getMethodName(),types); //获取对应的方法
        Object result=method.invoke(service,params);
        return result;
    }
}
